From ff3dfde07d170c43ed2e06bddbf8f093d7a49fcf Mon Sep 17 00:00:00 2001 From: "hollisb@localhost" Date: Mon, 18 Sep 2006 12:48:56 -0500 Subject: [PATCH] [POWERPC] merge with xen-unstable.hg Signed-off-by: Hollis Blanchard --- tools/libxc/powerpc64/Makefile | 3 + tools/libxc/powerpc64/xc_linux_build.c | 166 ++++++++++++------ xen/arch/powerpc/0opt.c | 4 +- xen/arch/powerpc/backtrace.c | 17 ++ xen/arch/powerpc/boot_of.c | 40 ++--- xen/arch/powerpc/dom0_ops.c | 17 ++ xen/arch/powerpc/domain.c | 22 +-- xen/arch/powerpc/elf32.c | 2 + xen/arch/powerpc/hcalls.c | 3 +- xen/arch/powerpc/iommu.c | 2 +- xen/arch/powerpc/mm.c | 37 ++-- xen/arch/powerpc/ofd_fixup.c | 29 ++- xen/arch/powerpc/oftree.h | 2 + xen/arch/powerpc/papr/xlate.c | 4 + xen/arch/powerpc/powerpc64/ppc970.c | 133 ++++++++------ xen/arch/powerpc/setup.c | 11 +- xen/arch/powerpc/shadow.c | 5 +- xen/arch/powerpc/usercopy.c | 47 ++++- xen/include/asm-powerpc/current.h | 2 +- xen/include/asm-powerpc/flushtlb.h | 3 - xen/include/asm-powerpc/guest_access.h | 2 +- xen/include/asm-powerpc/io.h | 2 + xen/include/asm-powerpc/mm.h | 4 +- .../asm-powerpc/powerpc64/ppc970-hid.h | 105 +++++++---- xen/include/asm-powerpc/powerpc64/processor.h | 24 +++ xen/include/asm-powerpc/processor.h | 7 +- xen/include/asm-powerpc/reg_defs.h | 1 + xen/include/asm-powerpc/shadow.h | 13 +- xen/include/asm-powerpc/smp.h | 2 +- xen/include/asm-powerpc/system.h | 4 +- 30 files changed, 467 insertions(+), 246 deletions(-) diff --git a/tools/libxc/powerpc64/Makefile b/tools/libxc/powerpc64/Makefile index 56ae5d52fb..d5c737f14f 100644 --- a/tools/libxc/powerpc64/Makefile +++ b/tools/libxc/powerpc64/Makefile @@ -1 +1,4 @@ GUEST_SRCS-y += powerpc64/xc_linux_build.c +GUEST_SRCS-y += powerpc64/ft_build.c + +CTRL_SRCS-y += powerpc64/xc_memory.c diff --git a/tools/libxc/powerpc64/xc_linux_build.c b/tools/libxc/powerpc64/xc_linux_build.c index fac90e06ee..fb0e25c542 100644 --- a/tools/libxc/powerpc64/xc_linux_build.c +++ b/tools/libxc/powerpc64/xc_linux_build.c @@ -27,14 +27,16 @@ #include #include +#include #include #include #include #include -/* XXX 64M hack */ -#define MEMSIZE (64UL << 20) +#include "ft_build.h" + #define INITRD_ADDR (24UL << 20) +#define DEVTREE_ADDR (16UL << 20) #define ALIGN_UP(addr,size) (((addr)+((size)-1))&(~((size)-1))) @@ -91,8 +93,8 @@ static int init_boot_vcpu( int xc_handle, int domid, struct domain_setup_info *dsi, - unsigned long dtb, - unsigned long kaddr) + unsigned long devtree_addr, + unsigned long kern_addr) { vcpu_guest_context_t ctxt; int rc; @@ -101,15 +103,15 @@ static int init_boot_vcpu( ctxt.user_regs.pc = dsi->v_kernentry; ctxt.user_regs.msr = 0; ctxt.user_regs.gprs[1] = 0; /* Linux uses its own stack */ - ctxt.user_regs.gprs[3] = dtb; - ctxt.user_regs.gprs[4] = kaddr; + ctxt.user_regs.gprs[3] = devtree_addr; + ctxt.user_regs.gprs[4] = kern_addr; ctxt.user_regs.gprs[5] = 0; /* There is a buggy kernel that does not zero the "local_paca", so * we must make sure this register is 0 */ ctxt.user_regs.gprs[13] = 0; DPRINTF("xc_vcpu_setvcpucontext:\n" - " pc 0x%"PRIx64", msr 0x016%"PRIx64"\n" + " pc 0x%016"PRIx64", msr 0x%016"PRIx64"\n" " r1-5 %016"PRIx64" %016"PRIx64" %016"PRIx64" %016"PRIx64 " %016"PRIx64"\n", ctxt.user_regs.pc, ctxt.user_regs.msr, @@ -156,30 +158,69 @@ static int install_image( return rc; } -/* XXX be more flexible about placement in memory */ -static int load_dtb( +static int load_devtree( int xc_handle, int domid, - const char *dtb_path, - unsigned long dtb_addr, - struct domain_setup_info *dsi, - xen_pfn_t *page_array) + xen_pfn_t *page_array, + void *devtree, + unsigned long devtree_addr, + unsigned long initrd_base, + unsigned long initrd_len, + start_info_t *si, + unsigned long si_addr) { - uint8_t *img; - unsigned long dtb_size; + uint32_t start_info[4] = {0, si_addr, 0, 0x1000}; + struct boot_param_header *header; + uint64_t *prop; + unsigned int devtree_size; + unsigned int proplen; int rc = 0; - img = load_file(dtb_path, &dtb_size); - if (img == NULL) { - rc = -1; - goto out; + header = devtree; + devtree_size = header->totalsize; + + DPRINTF("adding initrd props\n"); + + /* initrd-start */ + prop = ft_get_prop(devtree, "/chosen/linux,initrd-start", &proplen); + if (prop == NULL) { + DPRINTF("couldn't find linux,initrd-start\n"); + return -1; } + if (proplen != sizeof(*prop)) { + DPRINTF("couldn't set linux,initrd-start (size %d)\n", proplen); + return -1; + } + *prop = initrd_base; - DPRINTF("copying device tree to 0x%lx[0x%lx]\n", dtb_addr, dtb_size); - rc = install_image(xc_handle, domid, page_array, img, dtb_addr, dtb_size); + /* initrd-end */ + prop = ft_get_prop(devtree, "/chosen/linux,initrd-end", &proplen); + if (prop == NULL) { + DPRINTF("couldn't find linux,initrd-end\n"); + return -1; + } + if (proplen != sizeof(*prop)) { + DPRINTF("couldn't set linux,initrd-end (size %d)\n", proplen); + return -1; + } + *prop = initrd_base + initrd_len; + + /* start-info (XXX being removed soon) */ + prop = ft_get_prop(devtree, "/xen/start-info", &proplen); + if (prop == NULL) { + DPRINTF("couldn't find /xen/start-info\n"); + return -1; + } + if (proplen != sizeof(start_info)) { + DPRINTF("couldn't set /xen/start-info (size %d)\n", proplen); + return -1; + } + memcpy(prop, start_info, proplen); + + DPRINTF("copying device tree to 0x%lx[0x%x]\n", DEVTREE_ADDR, devtree_size); + rc = install_image(xc_handle, domid, page_array, devtree, DEVTREE_ADDR, + devtree_size); -out: - free(img); return rc; } @@ -294,17 +335,16 @@ out: } static unsigned long create_start_info(start_info_t *si, - unsigned int console_evtchn, unsigned int store_evtchn) + unsigned int console_evtchn, unsigned int store_evtchn, + unsigned long nr_pages) { - unsigned long eomem; unsigned long si_addr; memset(si, 0, sizeof(*si)); snprintf(si->magic, sizeof(si->magic), "xen-%d.%d-powerpc64HV", 3, 0); - eomem = MEMSIZE; - si->nr_pages = eomem >> PAGE_SHIFT; - si->shared_info = eomem - (PAGE_SIZE * 1); + si->nr_pages = nr_pages; + si->shared_info = (nr_pages - 1) << PAGE_SHIFT; si->store_mfn = si->nr_pages - 2; si->store_evtchn = store_evtchn; si->console.domU.mfn = si->nr_pages - 3; @@ -314,24 +354,24 @@ static unsigned long create_start_info(start_info_t *si, return si_addr; } -static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array) +static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array, + unsigned long *nr_pages) { - int nr_pages; int rc; DPRINTF("xc_get_tot_pages\n"); - nr_pages = xc_get_tot_pages(xc_handle, domid); - DPRINTF(" 0x%x\n", nr_pages); + *nr_pages = xc_get_tot_pages(xc_handle, domid); + DPRINTF(" 0x%lx\n", *nr_pages); - *page_array = malloc(nr_pages * sizeof(xen_pfn_t)); + *page_array = malloc(*nr_pages * sizeof(xen_pfn_t)); if (*page_array == NULL) { perror("malloc"); return -1; } DPRINTF("xc_get_pfn_list\n"); - rc = xc_get_pfn_list(xc_handle, domid, *page_array, nr_pages); - if (rc != nr_pages) { + rc = xc_get_pfn_list(xc_handle, domid, *page_array, *nr_pages); + if (rc != *nr_pages) { perror("Could not get the page frame list"); return -1; } @@ -339,6 +379,11 @@ static int get_page_array(int xc_handle, int domid, xen_pfn_t **page_array) return 0; } +static void free_page_array(xen_pfn_t *page_array) +{ + free(page_array); +} + int xc_linux_build(int xc_handle, @@ -351,57 +396,70 @@ int xc_linux_build(int xc_handle, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, - unsigned long *console_mfn) + unsigned long *console_mfn, + void *devtree) { + start_info_t si; struct domain_setup_info dsi; xen_pfn_t *page_array = NULL; + unsigned long nr_pages; + unsigned long devtree_addr = 0; unsigned long kern_addr; - unsigned long dtb_addr; - unsigned long si_addr; unsigned long initrd_base = 0; unsigned long initrd_len = 0; - start_info_t si; + unsigned long si_addr; int rc = 0; - if (get_page_array(xc_handle, domid, &page_array)) { + DPRINTF("%s\n", __func__); + + if (get_page_array(xc_handle, domid, &page_array, &nr_pages)) { rc = -1; goto out; } + DPRINTF("loading image '%s'\n", image_name); if (load_kernel(xc_handle, domid, image_name, &dsi, page_array)) { rc = -1; goto out; } kern_addr = 0; - if (initrd_name && initrd_name[0] != '\0' && - load_initrd(xc_handle, domid, page_array, initrd_name, &initrd_base, - &initrd_len)) { - rc = -1; - goto out; - } - /* XXX install initrd addr/len into device tree */ - - dtb_addr = (16 << 20); - if (load_dtb(xc_handle, domid, "/root/DomU.dtb", dtb_addr, &dsi, page_array)) { - dtb_addr = 0; + if (initrd_name && initrd_name[0] != '\0') { + DPRINTF("loading initrd '%s'\n", initrd_name); + if (load_initrd(xc_handle, domid, page_array, initrd_name, + &initrd_base, &initrd_len)) { + rc = -1; + goto out; + } } - si_addr = create_start_info(&si, console_evtchn, store_evtchn); + /* start_info stuff: about to be removed */ + si_addr = create_start_info(&si, console_evtchn, store_evtchn, nr_pages); *console_mfn = page_array[si.console.domU.mfn]; *store_mfn = page_array[si.store_mfn]; - if (install_image(xc_handle, domid, page_array, &si, si_addr, sizeof(start_info_t))) { rc = -1; goto out; } - if (init_boot_vcpu(xc_handle, domid, &dsi, dtb_addr, kern_addr)) { + if (devtree) { + DPRINTF("loading flattened device tree\n"); + devtree_addr = DEVTREE_ADDR; + if (load_devtree(xc_handle, domid, page_array, devtree, devtree_addr, + initrd_base, initrd_len, &si, si_addr)) { + DPRINTF("couldn't load flattened device tree.\n"); + rc = -1; + goto out; + } + } + + if (init_boot_vcpu(xc_handle, domid, &dsi, devtree_addr, kern_addr)) { rc = -1; goto out; } out: + free_page_array(page_array); return rc; } diff --git a/xen/arch/powerpc/0opt.c b/xen/arch/powerpc/0opt.c index 4247941f58..6d85e63c9e 100644 --- a/xen/arch/powerpc/0opt.c +++ b/xen/arch/powerpc/0opt.c @@ -19,10 +19,10 @@ */ #include -#include +#include extern void __cmpxchg_called_with_bad_pointer(void); void __cmpxchg_called_with_bad_pointer(void) { - trap(); + BUG(); } diff --git a/xen/arch/powerpc/backtrace.c b/xen/arch/powerpc/backtrace.c index da00ccdc0d..ec35d38d9a 100644 --- a/xen/arch/powerpc/backtrace.c +++ b/xen/arch/powerpc/backtrace.c @@ -191,3 +191,20 @@ void show_backtrace(ulong sp, ulong lr, ulong pc) backtrace(sp, lr, pc); console_end_sync(); } + +void __warn(char *file, int line) +{ + ulong sp; + ulong lr; + + console_start_sync(); + printk("WARN at %s:%d\n", file, line); + + sp = (ulong)__builtin_frame_address(0); + lr = (ulong)__builtin_return_address(0); + + backtrace(sp, lr, lr); + console_end_sync(); +} + + diff --git a/xen/arch/powerpc/boot_of.c b/xen/arch/powerpc/boot_of.c index 619dd2717b..eca84665fd 100644 --- a/xen/arch/powerpc/boot_of.c +++ b/xen/arch/powerpc/boot_of.c @@ -31,6 +31,7 @@ #include #include "exceptions.h" #include "of-devtree.h" +#include "oftree.h" /* Secondary processors use this for handshaking with main processor. */ volatile unsigned int __spin_ack; @@ -38,7 +39,6 @@ volatile unsigned int __spin_ack; static ulong of_vec; static ulong of_msr; static int of_out; -static ofdn_t boot_cpu; static char bootargs[256]; #define COMMAND_LINE_SIZE 512 @@ -669,7 +669,7 @@ static int boot_of_fixup_chosen(void *mem) dn = ofd_node_find(mem, ofpath); if (dn <= 0) of_panic("no node for: %s\n", ofpath); - boot_cpu = dn; + ofd_boot_cpu = dn; val = dn; dn = ofd_node_find(mem, "/chosen"); @@ -681,7 +681,7 @@ static int boot_of_fixup_chosen(void *mem) } else { of_printf("*** can't find path to booting cpu, " "SMP is disabled\n"); - boot_cpu = -1; + ofd_boot_cpu = -1; } } return rc; @@ -773,7 +773,7 @@ static void __init boot_of_fix_maple(void) } } -static int __init boot_of_serial(void *oftree) +static int __init boot_of_serial(void *oft) { int n; int p; @@ -805,7 +805,7 @@ static int __init boot_of_serial(void *oftree) continue; of_printf("pruning `%s' from devtree\n", buf); - rc = ofd_prune_path(oftree, buf); + rc = ofd_prune_path(oft, buf); if (rc < 0) of_panic("prune of `%s' failed\n", buf); } @@ -858,8 +858,8 @@ static int __init boot_of_serial(void *oftree) static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) { static module_t mods[3]; - void *oftree; - ulong oftree_sz = 48 * PAGE_SIZE; + void *oft; + ulong oft_sz = 48 * PAGE_SIZE; ulong mod0_start; ulong mod0_size; static const char sepr[] = " -- "; @@ -922,28 +922,28 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) } /* snapshot the tree */ - oftree = (void*)find_space(oftree_sz, PAGE_SIZE, mbi); - if (oftree == 0) + oft = (void*)find_space(oft_sz, PAGE_SIZE, mbi); + if (oft == 0) of_panic("Could not allocate OFD tree\n"); - of_printf("creating oftree\n"); + of_printf("creating oft\n"); of_test("package-to-path"); - oftree = ofd_create(oftree, oftree_sz); - pkg_save(oftree); + oft = ofd_create(oft, oft_sz); + pkg_save(oft); - if (ofd_size(oftree) > oftree_sz) + if (ofd_size(oft) > oft_sz) of_panic("Could not fit all of native devtree\n"); - boot_of_fixup_refs(oftree); - boot_of_fixup_chosen(oftree); + boot_of_fixup_refs(oft); + boot_of_fixup_chosen(oft); - if (ofd_size(oftree) > oftree_sz) + if (ofd_size(oft) > oft_sz) of_panic("Could not fit all devtree fixups\n"); - ofd_walk(oftree, OFD_ROOT, /* add_hype_props */ NULL, 2); + ofd_walk(oft, OFD_ROOT, /* add_hype_props */ NULL, 2); - mods[1].mod_start = (ulong)oftree; - mods[1].mod_end = mods[1].mod_start + oftree_sz; + mods[1].mod_start = (ulong)oft; + mods[1].mod_end = mods[1].mod_start + oft_sz; of_printf("%s: mod[1] @ 0x%016x[0x%x]\n", __func__, mods[1].mod_start, mods[1].mod_end); @@ -952,7 +952,7 @@ static void boot_of_module(ulong r3, ulong r4, multiboot_info_t *mbi) mbi->mods_count = 2; mbi->mods_addr = (u32)mods; - boot_of_serial(oftree); + boot_of_serial(oft); } static int __init boot_of_cpus(void) diff --git a/xen/arch/powerpc/dom0_ops.c b/xen/arch/powerpc/dom0_ops.c index 975e11d65d..059a2994f4 100644 --- a/xen/arch/powerpc/dom0_ops.c +++ b/xen/arch/powerpc/dom0_ops.c @@ -27,6 +27,7 @@ #include #include #include +#include void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *); void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c) @@ -92,6 +93,22 @@ long arch_do_domctl(struct xen_domctl *domctl, } } break; + case XEN_DOMCTL_real_mode_area: + { + struct domain *d; + unsigned int log = domctl->u.real_mode_area.log; + + d = find_domain_by_id(domctl->domain); + if (d == NULL) + return -ESRCH; + + if (!cpu_rma_valid(log)) + return -EINVAL; + + ret = allocate_rma(d, log - PAGE_SHIFT); + put_domain(d); + } + break; default: ret = -ENOSYS; diff --git a/xen/arch/powerpc/domain.c b/xen/arch/powerpc/domain.c index 4ff298be9a..77df5a613f 100644 --- a/xen/arch/powerpc/domain.c +++ b/xen/arch/powerpc/domain.c @@ -75,11 +75,6 @@ unsigned long hypercall_create_continuation(unsigned int op, int arch_domain_create(struct domain *d) { - unsigned long rma_base; - unsigned long rma_sz; - uint rma_order_pages; - int rc; - if (d->domain_id == IDLE_DOMAIN_ID) { d->shared_info = (void *)alloc_xenheap_page(); clear_page(d->shared_info); @@ -87,20 +82,6 @@ int arch_domain_create(struct domain *d) return 0; } - /* allocate the real mode area */ - rma_order_pages = cpu_default_rma_order_pages(); - d->max_pages = 1UL << rma_order_pages; - d->tot_pages = 0; - - rc = allocate_rma(d, rma_order_pages); - if (rc) - return rc; - rma_base = page_to_maddr(d->arch.rma_page); - rma_sz = rma_size(rma_order_pages); - - d->shared_info = (shared_info_t *) - (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); - d->arch.large_page_sizes = cpu_large_page_orders( d->arch.large_page_order, ARRAY_SIZE(d->arch.large_page_order)); @@ -264,7 +245,8 @@ void sync_vcpu_execstate(struct vcpu *v) void domain_relinquish_resources(struct domain *d) { - free_domheap_pages(d->arch.rma_page, d->arch.rma_order); + if (d->arch.rma_page) + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); free_extents(d); } diff --git a/xen/arch/powerpc/elf32.c b/xen/arch/powerpc/elf32.c index 9a88fabc7e..7793c3ea37 100644 --- a/xen/arch/powerpc/elf32.c +++ b/xen/arch/powerpc/elf32.c @@ -1,5 +1,7 @@ #define parseelfimage parseelfimage_32 #define loadelfimage loadelfimage_32 +#define xen_elfnote_string xen_elfnote_string32 +#define xen_elfnote_numeric xen_elfnote_numeric32 #define ELFSIZE 32 #include "../../common/elf.c" diff --git a/xen/arch/powerpc/hcalls.c b/xen/arch/powerpc/hcalls.c index e48ed9601f..27064b2ca0 100644 --- a/xen/arch/powerpc/hcalls.c +++ b/xen/arch/powerpc/hcalls.c @@ -112,9 +112,8 @@ static void do_ni_papr_hypercall(struct cpu_user_regs *regs) { struct vcpu *v = get_current(); - printk("unsupported hcall 0x%lx was called by dom0x%x\n", + printk("unsupported PAPR hcall 0x%lx was called by dom0x%x\n", regs->gprs[3], v->domain->domain_id); - debugger_trap_immediate(); regs->gprs[3] = H_Parameter; } diff --git a/xen/arch/powerpc/iommu.c b/xen/arch/powerpc/iommu.c index a0594f7a30..5086bf0ebf 100644 --- a/xen/arch/powerpc/iommu.c +++ b/xen/arch/powerpc/iommu.c @@ -52,7 +52,7 @@ int iommu_put(u32 buid, ulong ioba, union tce tce) pfn = tce.tce_bits.tce_rpn; mfn = pfn2mfn(d, pfn, &mtype); - if (mfn > 0) { + if (mfn != INVALID_MFN) { #ifdef DEBUG printk("%s: ioba=0x%lx pfn=0x%lx mfn=0x%lx\n", __func__, ioba, pfn, mfn); diff --git a/xen/arch/powerpc/mm.c b/xen/arch/powerpc/mm.c index 1ca8f9fda4..1014c041cf 100644 --- a/xen/arch/powerpc/mm.c +++ b/xen/arch/powerpc/mm.c @@ -301,27 +301,41 @@ uint allocate_extents(struct domain *d, uint nrpages, uint rma_nrpages) return total_nrpages; } - -int allocate_rma(struct domain *d, unsigned int order_pages) + +int allocate_rma(struct domain *d, unsigned int order) { + struct vcpu *v; ulong rma_base; - ulong rma_sz = rma_size(order_pages); + ulong rma_sz; + + if (d->arch.rma_page) + free_domheap_pages(d->arch.rma_page, d->arch.rma_order); - d->arch.rma_page = alloc_domheap_pages(d, order_pages, 0); + d->arch.rma_page = alloc_domheap_pages(d, order, 0); if (d->arch.rma_page == NULL) { - DPRINTK("Could not allocate order_pages=%d RMA for domain %u\n", - order_pages, d->domain_id); + DPRINTK("Could not allocate order=%d RMA for domain %u\n", + order, d->domain_id); return -ENOMEM; } - d->arch.rma_order = order_pages; + d->arch.rma_order = order; rma_base = page_to_maddr(d->arch.rma_page); + rma_sz = rma_size(d->arch.rma_order); BUG_ON(rma_base & (rma_sz - 1)); /* check alignment */ - /* XXX */ + /* XXX shouldn't be needed */ printk("clearing RMA: 0x%lx[0x%lx]\n", rma_base, rma_sz); memset((void *)rma_base, 0, rma_sz); + d->shared_info = (shared_info_t *) + (rma_addr(&d->arch, RMA_SHARED_INFO) + rma_base); + + /* if there are already running vcpus, adjust v->vcpu_info */ + /* XXX untested */ + for_each_vcpu(d, v) { + v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; + } + return 0; } @@ -331,6 +345,10 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type) ulong rma_size_mfn = 1UL << d->arch.rma_order; struct page_extents *pe; + if (type) + *type = PFN_TYPE_NONE; + + /* quick tests first */ if (pfn < rma_size_mfn) { if (type) *type = PFN_TYPE_RMA; @@ -344,7 +362,6 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type) return pfn; } - /* quick tests first */ list_for_each_entry (pe, &d->arch.extent_list, pe_list) { uint end_pfn = pe->pfn + (1 << pe->order); @@ -364,7 +381,7 @@ ulong pfn2mfn(struct domain *d, long pfn, int *type) } BUG(); - return 0; + return INVALID_MFN; } void guest_physmap_add_page( diff --git a/xen/arch/powerpc/ofd_fixup.c b/xen/arch/powerpc/ofd_fixup.c index e20978d9b1..9fe88df714 100644 --- a/xen/arch/powerpc/ofd_fixup.c +++ b/xen/arch/powerpc/ofd_fixup.c @@ -28,6 +28,8 @@ #undef RTAS +ofdn_t ofd_boot_cpu; + #ifdef PAPR_VTERM static ofdn_t ofd_vdevice_vty(void *m, ofdn_t p, struct domain *d) { @@ -172,24 +174,21 @@ static ofdn_t ofd_cpus_props(void *m, struct domain *d) #endif c = ofd_node_find_by_prop(m, n, "device_type", cpu, sizeof (cpu)); + if (ofd_boot_cpu == -1) + ofd_boot_cpu = c; while (c > 0) { - ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE; - ofd_prop_add(m, c, "ibm,pft-size", - ibm_pft_size, sizeof (ibm_pft_size)); - - /* FIXME: Check the the "l2-cache" property who's - * contents is an orphaned phandle? */ - c = ofd_node_find_next(m, c); - - /* Since we are not MP yet we can prune the rest of the CPUs */ - while (c > 0) { - ofdn_t nc; - - nc = ofd_node_find_next(m, c); + /* Since we are not MP yet we prune all but the booting cpu */ + if (c == ofd_boot_cpu) { + ibm_pft_size[1] = d->arch.htab.log_num_ptes + LOG_PTE_SIZE; + ofd_prop_add(m, c, "ibm,pft-size", + ibm_pft_size, sizeof (ibm_pft_size)); + + /* FIXME: Check the the "l2-cache" property who's + * contents is an orphaned phandle? */ + } else ofd_node_prune(m, c); - c = nc; - } + c = ofd_node_find_next(m, c); } return n; diff --git a/xen/arch/powerpc/oftree.h b/xen/arch/powerpc/oftree.h index f828e96c1a..d1ad7a1598 100644 --- a/xen/arch/powerpc/oftree.h +++ b/xen/arch/powerpc/oftree.h @@ -21,10 +21,12 @@ #ifndef _OFTREE_H #define _OFTREE_H #include +#include "of-devtree.h" extern ulong oftree; extern ulong oftree_len; extern ulong oftree_end; +extern ofdn_t ofd_boot_cpu; extern int ofd_dom0_fixup(struct domain *d, ulong mem, start_info_t *si); extern void ofd_memory_props(void *m, struct domain *d); diff --git a/xen/arch/powerpc/papr/xlate.c b/xen/arch/powerpc/papr/xlate.c index efc47a9e1b..7d9d9620f3 100644 --- a/xen/arch/powerpc/papr/xlate.c +++ b/xen/arch/powerpc/papr/xlate.c @@ -164,6 +164,10 @@ static void h_enter(struct cpu_user_regs *regs) lpn = pte.bits.rpn & lpn; rpn = pfn2mfn(d, lpn, &mtype); + if (rpn == INVALID_MFN) { + regs->gprs[3] = H_Parameter; + return; + } if (mtype == PFN_TYPE_IO) { /* only a privilaged dom can access outside IO space */ diff --git a/xen/arch/powerpc/powerpc64/ppc970.c b/xen/arch/powerpc/powerpc64/ppc970.c index 9c9d5c2b82..d9f01b727f 100644 --- a/xen/arch/powerpc/powerpc64/ppc970.c +++ b/xen/arch/powerpc/powerpc64/ppc970.c @@ -32,21 +32,19 @@ #undef SERIALIZE -extern volatile struct processor_area * volatile global_cpu_table[]; - struct rma_settings { int order; - int rmlr0; - int rmlr12; + int rmlr_0; + int rmlr_1_2; }; static struct rma_settings rma_orders[] = { - { .order = 26, .rmlr0 = 0, .rmlr12 = 3, }, /* 64 MB */ - { .order = 27, .rmlr0 = 1, .rmlr12 = 3, }, /* 128 MB */ - { .order = 28, .rmlr0 = 1, .rmlr12 = 0, }, /* 256 MB */ - { .order = 30, .rmlr0 = 0, .rmlr12 = 2, }, /* 1 GB */ - { .order = 34, .rmlr0 = 0, .rmlr12 = 1, }, /* 16 GB */ - { .order = 38, .rmlr0 = 0, .rmlr12 = 0, }, /* 256 GB */ + { .order = 26, .rmlr_0 = 0, .rmlr_1_2 = 3, }, /* 64 MB */ + { .order = 27, .rmlr_0 = 1, .rmlr_1_2 = 3, }, /* 128 MB */ + { .order = 28, .rmlr_0 = 1, .rmlr_1_2 = 0, }, /* 256 MB */ + { .order = 30, .rmlr_0 = 0, .rmlr_1_2 = 2, }, /* 1 GB */ + { .order = 34, .rmlr_0 = 0, .rmlr_1_2 = 1, }, /* 16 GB */ + { .order = 38, .rmlr_0 = 0, .rmlr_1_2 = 0, }, /* 256 GB */ }; static uint log_large_page_sizes[] = { @@ -68,6 +66,11 @@ unsigned int cpu_default_rma_order_pages(void) return rma_orders[0].order - PAGE_SHIFT; } +int cpu_rma_valid(unsigned int log) +{ + return cpu_find_rma(log) != NULL; +} + unsigned int cpu_large_page_orders(uint *sizes, uint max) { uint i = 0; @@ -85,12 +88,36 @@ unsigned int cpu_extent_order(void) return log_large_page_sizes[0] - PAGE_SHIFT; } +static u64 cpu0_hids[6]; +static u64 cpu0_hior; + void cpu_initialize(int cpuid) { ulong r1, r2; + union hid0 hid0; + union hid1 hid1; + union hid4 hid4; + union hid5 hid5; + __asm__ __volatile__ ("mr %0, 1" : "=r" (r1)); __asm__ __volatile__ ("mr %0, 2" : "=r" (r2)); + if (cpuid == 0) { + /* we can assume that these are sane to start with. We + * _do_not_ store the results in case we want to mess with them + * on a per-cpu basis later. */ + cpu0_hids[0] = mfhid0(); + cpu0_hids[1] = mfhid1(); + cpu0_hids[4] = mfhid4(); + cpu0_hids[5] = mfhid5(); + cpu0_hior = 0; + } + + hid0.word = cpu0_hids[0]; + hid1.word = cpu0_hids[1]; + hid4.word = cpu0_hids[4]; + hid5.word = cpu0_hids[5]; + /* This is SMP safe because the compiler must use r13 for it. */ parea = global_cpu_table[cpuid]; ASSERT(parea != NULL); @@ -103,25 +130,21 @@ void cpu_initialize(int cpuid) mtdec(timebase_freq); mthdec(timebase_freq); - union hid0 hid0; + hid0.bits.nap = 1; /* NAP */ + hid0.bits.dpm = 1; /* Dynamic Power Management */ + hid0.bits.nhr = 0; /* ! Not Hard Reset */ + hid0.bits.hdice_en = 1; /* enable HDEC */ + hid0.bits.en_therm = 0; /* ! Enable ext thermal ints */ + /* onlu debug Xen should do this */ + hid0.bits.en_attn = 1; /* Enable attn instruction */ - hid0.word = mfhid0(); - hid0.bits.nap = 1; - hid0.bits.dpm = 1; - hid0.bits.nhr = 1; - hid0.bits.hdice = 1; /* enable HDEC */ - hid0.bits.eb_therm = 1; - hid0.bits.en_attn = 1; #ifdef SERIALIZE - ulong s = 0; - - s |= 1UL << (63-0); /* one_ppc */ - s |= 1UL << (63-2); /* isync_sc */ - s |= 1UL << (63-16); /* inorder */ + hid0.bits.one_ppc = 1; + hid0.bits.isync_sc = 1; + hid0.bits.inorder = 1; /* may not want these */ - s |= 1UL << (63-1); /* do_single */ - s |= 1UL << (63-3); /* ser-gp */ - hid0.word |= s; + hid0.bits.do_single = 1; + hid0.bits.ser-gp = 1; #endif printk("CPU #%d: Hello World! SP = %lx TOC = %lx HID0 = %lx\n", @@ -129,32 +152,42 @@ void cpu_initialize(int cpuid) mthid0(hid0.word); - union hid1 hid1; - - hid1.word = mfhid1(); - hid1.bits.bht_pm = 7; - hid1.bits.en_ls = 1; + hid1.bits.bht_pm = 7; /* branch history table prediction mode */ + hid1.bits.en_ls = 1; /* enable link stack */ - hid1.bits.en_cc = 1; - hid1.bits.en_ic = 1; + hid1.bits.en_cc = 1; /* enable count cache */ + hid1.bits.en_ic = 1; /* enable inst cache */ - hid1.bits.pf_mode = 2; + hid1.bits.pf_mode = 2; /* prefetch mode */ - hid1.bits.en_if_cach = 1; - hid1.bits.en_ic_rec = 1; - hid1.bits.en_id_rec = 1; - hid1.bits.en_er_rec = 1; + hid1.bits.en_if_cach = 1; /* i-fetch cacheability control */ + hid1.bits.en_ic_rec = 1; /* i-cache parity error recovery */ + hid1.bits.en_id_rec = 1; /* i-dir parity error recovery */ + hid1.bits.en_er_rec = 1; /* i-ERAT parity error recovery */ - hid1.bits.en_sp_itw = 1; + hid1.bits.en_sp_itw = 1; /* En speculative tablewalks */ mthid1(hid1.word); - union hid5 hid5; + /* no changes to hid4 but we want to make sure that secondaries + * are sane */ + hid4.bits.lg_pg_dis = 0; /* make sure we enable large pages */ + mthid4(hid4.word); - hid5.word = mfhid5(); - hid5.bits.DCBZ_size = 0; - hid5.bits.DCBZ32_ill = 0; + hid5.bits.DCBZ_size = 0; /* make dcbz size 32 bytes */ + hid5.bits.DCBZ32_ill = 0; /* make dzbz 32byte illeagal */ mthid5(hid5.word); +#ifdef DUMP_HIDS + printk("hid0 0x%016lx\n" + "hid1 0x%016lx\n" + "hid4 0x%016lx\n" + "hid5 0x%016lx\n", + mfhid0(), mfhid1(), mfhid4(), mfhid5()); +#endif + + mthior(cpu0_hior); + + /* for good luck */ __asm__ __volatile__("isync; slbia; isync" : : : "memory"); } @@ -166,18 +199,18 @@ void cpu_init_vcpu(struct vcpu *v) hid4.word = mfhid4(); - hid4.bits.lpes0 = 0; /* exceptions set MSR_HV=1 */ - hid4.bits.lpes1 = 1; /* RMA applies */ + hid4.bits.lpes_0 = 0; /* external exceptions set MSR_HV=1 */ + hid4.bits.lpes_1 = 1; /* RMA applies */ - hid4.bits.rmor = page_to_maddr(d->arch.rma_page) >> 26; + hid4.bits.rmor_0_15 = page_to_maddr(d->arch.rma_page) >> 26; - hid4.bits.lpid01 = d->domain_id & 3; - hid4.bits.lpid25 = (d->domain_id >> 2) & 0xf; + hid4.bits.lpid_0_1 = d->domain_id & 3; + hid4.bits.lpid_2_5 = (d->domain_id >> 2) & 0xf; rma_settings = cpu_find_rma(d->arch.rma_order + PAGE_SHIFT); ASSERT(rma_settings != NULL); - hid4.bits.rmlr0 = rma_settings->rmlr0; - hid4.bits.rmlr12 = rma_settings->rmlr12; + hid4.bits.rmlr_0 = rma_settings->rmlr_0; + hid4.bits.rmlr_1_2 = rma_settings->rmlr_1_2; v->arch.cpu.hid4.word = hid4.word; } diff --git a/xen/arch/powerpc/setup.c b/xen/arch/powerpc/setup.c index 9fd7fb3e83..ea11b01c8d 100644 --- a/xen/arch/powerpc/setup.c +++ b/xen/arch/powerpc/setup.c @@ -77,6 +77,7 @@ cpumask_t cpu_present_map; cpumask_t cpu_possible_map; /* XXX get this from ISA node in device tree */ +void *vgabase; ulong isa_io_base; struct ns16550_defaults ns16550; @@ -255,7 +256,6 @@ static int kick_secondary_cpus(int maxcpus) break; init_parea(cpuid); cpu_set(cpuid, cpu_online_map); - cpu_set(cpuid, cpu_possible_map); } return 0; @@ -339,7 +339,7 @@ static void __init __start_xen(multiboot_info_t *mbi) #endif /* Deal with secondary processors. */ - if (opt_nosmp) { + if (opt_nosmp || ofd_boot_cpu == -1) { printk("nosmp: leaving secondary processors spinning forever\n"); } else { printk("spinning up at most %d total processors ...\n", max_cpus); @@ -350,8 +350,13 @@ static void __init __start_xen(multiboot_info_t *mbi) /* Create initial domain 0. */ dom0 = domain_create(0); - if ((dom0 == NULL) || (alloc_vcpu(dom0, 0, 0) == NULL)) + if (dom0 == NULL) panic("Error creating domain 0\n"); + dom0->max_pages = ~0U; + if (0 > allocate_rma(dom0, cpu_default_rma_order_pages())) + panic("Error allocating domain 0 RMA\n"); + if (NULL == alloc_vcpu(dom0, 0, 0)) + panic("Error creating domain 0 vcpu 0\n"); set_bit(_DOMF_privileged, &dom0->domain_flags); /* post-create hooks sets security label */ diff --git a/xen/arch/powerpc/shadow.c b/xen/arch/powerpc/shadow.c index e311b53dfd..3694d27e77 100644 --- a/xen/arch/powerpc/shadow.c +++ b/xen/arch/powerpc/shadow.c @@ -78,7 +78,6 @@ unsigned int shadow_set_allocation(struct domain *d, unsigned int megabytes, int *preempted) { - unsigned int rc; uint pages; uint p; uint order; @@ -91,7 +90,7 @@ unsigned int shadow_set_allocation(struct domain *d, if (megabytes == 0) { /* old management tools */ megabytes = 1; /* 1/64th of 64M */ - printk("%s: Fix management tools to set and get shadow/htab values\n" + printk("%s: WARNING!!: Update your managment tools\n" " using %d MiB htab\n", __func__, megabytes); } @@ -112,7 +111,7 @@ unsigned int shadow_set_allocation(struct domain *d, for (p = 0; p < (1 << order); p++) clear_page((void *)(addr + (p << PAGE_SHIFT))); - return rc; + return 0; } int shadow_domctl(struct domain *d, diff --git a/xen/arch/powerpc/usercopy.c b/xen/arch/powerpc/usercopy.c index b555586007..8ac16e6c69 100644 --- a/xen/arch/powerpc/usercopy.c +++ b/xen/arch/powerpc/usercopy.c @@ -47,14 +47,24 @@ static unsigned long paddr_to_maddr(unsigned long paddr) pfn = pa >> PAGE_SHIFT; pa = pfn2mfn(d, pfn, &mtype); + if (pa == INVALID_MFN) { + printk("%s: Dom:%d bad paddr: 0x%lx\n", + __func__, d->domain_id, paddr); + return 0; + } switch (mtype) { - case PFN_TYPE_RMA: - case PFN_TYPE_LOGICAL: - break; - default: - panic("%s: called with bad memory address type: 0x%lx\n", - __func__, paddr); - break; + case PFN_TYPE_RMA: + case PFN_TYPE_LOGICAL: + break; + case PFN_TYPE_REMOTE: + printk("%s: Dom:%d paddr: 0x%lx type: REMOTE\n", + __func__, d->domain_id, paddr); + WARN(); + break; + default: + panic("%s: Dom:%d paddr: 0x%lx bad type:0x%x\n", + __func__, d->domain_id, paddr, mtype); + break; } pa <<= PAGE_SHIFT; pa |= offset; @@ -85,6 +95,9 @@ xencomm_copy_from_guest(void *to, const void *from, unsigned int n, /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)from); + if (desc == NULL) + return n; + if (desc->magic != XENCOMM_MAGIC) { printk("%s: error: %p magic was 0x%x\n", __func__, desc, desc->magic); @@ -117,6 +130,9 @@ xencomm_copy_from_guest(void *to, const void *from, unsigned int n, unsigned int bytes = min(chunksz, n - to_pos); src_maddr = paddr_to_maddr(src_paddr + chunk_skip); + if (src_maddr == 0) + return n - to_pos; + if (xencomm_debug) printk("%lx[%d] -> %lx\n", src_maddr, bytes, dest); memcpy((void *)dest, (void *)src_maddr, bytes); @@ -153,6 +169,9 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n, /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)to); + if (desc == NULL) + return n; + if (desc->magic != XENCOMM_MAGIC) { printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic); return n; @@ -184,6 +203,9 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n, unsigned int bytes = min(chunksz, n - from_pos); dest_maddr = paddr_to_maddr(dest_paddr + chunk_skip); + if (dest_maddr == 0) + return -1; + if (xencomm_debug) printk("%lx[%d] -> %lx\n", source, bytes, dest_maddr); memcpy((void *)dest_maddr, (void *)source, bytes); @@ -199,16 +221,19 @@ xencomm_copy_to_guest(void *to, const void *from, unsigned int n, /* Offset page addresses in 'handle' to skip 'bytes' bytes. Set completely * exhausted pages to XENCOMM_INVALID. */ -void xencomm_add_offset(void *handle, unsigned int bytes) +int xencomm_add_offset(void *handle, unsigned int bytes) { struct xencomm_desc *desc; int i = 0; /* first we need to access the descriptor */ desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)handle); + if (desc == NULL) + return -1; + if (desc->magic != XENCOMM_MAGIC) { printk("%s error: %p magic was 0x%x\n", __func__, desc, desc->magic); - return; + return -1; } /* iterate through the descriptor incrementing addresses */ @@ -230,6 +255,7 @@ void xencomm_add_offset(void *handle, unsigned int bytes) } bytes -= chunk_skip; } + return 0; } int xencomm_handle_is_null(void *ptr) @@ -237,6 +263,9 @@ int xencomm_handle_is_null(void *ptr) struct xencomm_desc *desc; desc = (struct xencomm_desc *)paddr_to_maddr((unsigned long)ptr); + if (desc == NULL) + return 1; return (desc->nr_addrs == 0); } + diff --git a/xen/include/asm-powerpc/current.h b/xen/include/asm-powerpc/current.h index f30aad20e2..e77c886b6b 100644 --- a/xen/include/asm-powerpc/current.h +++ b/xen/include/asm-powerpc/current.h @@ -27,8 +27,8 @@ struct vcpu; +extern volatile struct processor_area * volatile global_cpu_table[]; register volatile struct processor_area *parea asm("r13"); - static inline struct vcpu *get_current(void) { return parea->cur_vcpu; diff --git a/xen/include/asm-powerpc/flushtlb.h b/xen/include/asm-powerpc/flushtlb.h index 9b77c46f1f..c33926a3ae 100644 --- a/xen/include/asm-powerpc/flushtlb.h +++ b/xen/include/asm-powerpc/flushtlb.h @@ -35,9 +35,6 @@ DECLARE_PER_CPU(u32, tlbflush_time); static inline int NEED_FLUSH(u32 cpu_stamp, u32 lastuse_stamp) { -#if 0 - trap(); -#endif return 0; } diff --git a/xen/include/asm-powerpc/guest_access.h b/xen/include/asm-powerpc/guest_access.h index 51f6d501c2..fcae9d5d31 100644 --- a/xen/include/asm-powerpc/guest_access.h +++ b/xen/include/asm-powerpc/guest_access.h @@ -25,7 +25,7 @@ extern unsigned long xencomm_copy_to_guest(void *to, const void *from, unsigned int len, unsigned int skip); extern unsigned long xencomm_copy_from_guest(void *to, const void *from, unsigned int len, unsigned int skip); -extern void xencomm_add_offset(void *handle, unsigned int bytes); +extern int xencomm_add_offset(void *handle, unsigned int bytes); extern int xencomm_handle_is_null(void *ptr); diff --git a/xen/include/asm-powerpc/io.h b/xen/include/asm-powerpc/io.h index 1e2d31cbb2..d0fa182605 100644 --- a/xen/include/asm-powerpc/io.h +++ b/xen/include/asm-powerpc/io.h @@ -40,6 +40,8 @@ extern ulong isa_io_base; #define readb(port) in_8((void *)(port)) #define writeb(val, port) out_8((void *)(port), val) +extern char *vgabase; +#define vga_writeb(val, port) out_8((void *)((ulong)(port) + vgabase), val) extern u8 in_8(const volatile u8 *addr); extern void out_8(volatile u8 *addr, int val); diff --git a/xen/include/asm-powerpc/mm.h b/xen/include/asm-powerpc/mm.h index a3eeecf542..7f658ad417 100644 --- a/xen/include/asm-powerpc/mm.h +++ b/xen/include/asm-powerpc/mm.h @@ -212,8 +212,6 @@ static inline int page_is_removable(struct page_info *page) return ((page->count_info & PGC_count_mask) == 1); } -#define set_machinetophys(_mfn, _pfn) (trap(), 0) - extern void synchronise_pagetables(unsigned long cpu_mask); /* XXX don't know what this is for */ @@ -236,6 +234,8 @@ extern int update_grant_va_mapping(unsigned long va, struct domain *, struct vcpu *); +#define INVALID_MFN (~0UL) +#define PFN_TYPE_NONE 0 #define PFN_TYPE_RMA 1 #define PFN_TYPE_LOGICAL 2 #define PFN_TYPE_IO 3 diff --git a/xen/include/asm-powerpc/powerpc64/ppc970-hid.h b/xen/include/asm-powerpc/powerpc64/ppc970-hid.h index c5054e92dd..70050039ab 100644 --- a/xen/include/asm-powerpc/powerpc64/ppc970-hid.h +++ b/xen/include/asm-powerpc/powerpc64/ppc970-hid.h @@ -29,22 +29,30 @@ union hid0 { struct hid0_bits { - ulong _unused_0_8: 9; - ulong nap: 1; - ulong _unused_10: 1; - ulong dpm: 1; /* Dynamic Power Management */ - ulong _unused_12_14: 3; - ulong nhr: 1; /* Not Hard Reset */ - ulong inorder: 1; + ulong one_ppc: 1; /* One PowerPC AS insn per dispatch group */ + ulong do_single: 1; /* Single group completion */ + ulong isync_sc: 1; /* Disable isync scoreboard optimization */ + ulong ser_gp: 1; /* Serial Group Dispatch */ + ulong _reserved_04_08: 5; + ulong nap: 1; /* Nap */ + ulong _reserved_10: 1; + ulong dpm: 1; /* Dynamic Power Management */ + ulong _reserved_12: 1; + ulong tg: 1; /* Perfmon threshold granualrity control */ + ulong hang_dis: 1; /* Disable cpu hang detection mechanism */ + ulong nhr: 1; /* Not Hard Reset */ + ulong inorder: 1; /* Serial Group Issue */ ulong _reserved17: 1; - ulong tb_ctrl: 1; - ulong ext_tb_enb: 1; /* timebase is linked to external clock */ - ulong _unused_20_22: 3; - ulong hdice: 1; /* HDEC enable */ - ulong eb_therm: 1; /* Enable ext thermal ints */ + ulong tb_ctrl: 1; /* Enable time base couting while stopped */ + ulong ext_tb_enb: 1; /* timebase is linked to external clock */ + ulong _unused_20_21: 2; + ulong ciabr_en: 1; /* CIABR enable */ + ulong hdice_en: 1; /* HDEC enable */ + ulong en_therm: 1; /* Enable ext thermal ints */ ulong _unused_25_30: 6; ulong en_attn: 1; /* Enable attn instruction */ - ulong _unused_32_63: 32; + ulong en_mck: 1; /* En external machine check interrupts */ + ulong _unused_33_63: 31; } bits; ulong word; }; @@ -62,11 +70,11 @@ union hid1 { ulong en_ic_rec: 1; /* i-cache parity error recovery */ ulong en_id_rec: 1; /* i-dir parity error recovery */ ulong en_er_rec: 1; /* i-ERAT parity error recovery */ - ulong ic_pe: 1; - ulong icd0_pe: 1; + ulong ic_pe: 1; /* Force instruction cache parity error */ + ulong icd0_pe: 1; /* Force insn cache dir 0 parity error */ ulong _reserved_16: 1; - ulong ier_pe: 1; - ulong en_sp_itw: 1; + ulong ier_pe: 1; /* force i-ERAT parity error (inject) */ + ulong en_sp_itw: 1; /* En speculative tablewalks */ ulong _reserved_19_63: 45; } bits; ulong word; @@ -74,32 +82,61 @@ union hid1 { union hid4 { struct hid4_bits { - ulong lpes0: 1; /* LPAR Environment Selector bit 0 */ - ulong rmlr12: 2; /* RMLR 1:2 */ - ulong lpid25: 4; /* LPAR ID bits 2:5 */ - ulong rmor: 16; /* real mode offset region */ - ulong rm_ci: 1; /* real mode cache-inhibit */ - ulong force_ai: 1; /* Force alignment interrupt */ - ulong _unused: 32; - ulong lpes1: 1; /* LPAR Environment Selector bit 1 */ - ulong rmlr0: 1; /* RMLR 0 */ + ulong lpes_0: 1; /* LPAR Environment Selector bit 0 */ + ulong rmlr_1_2: 2; /* RMLR 1:2 */ + ulong lpid_2_5: 4; /* LPAR ID bits 2:5 */ + ulong rmor_0_15: 16; /* real mode offset region */ + ulong rm_ci: 1; /* real mode cache-inhibit */ + ulong force_ai: 1; /* Force alignment interrupt */ + ulong dis_pref: 1; /* disable prefetching */ + ulong res_pref: 1; /* reset data prefetching mechanism */ + ulong en_sp_dtw: 1; /* enable speculative load tablewalk */ + ulong l1dc_flsh: 1; /* L1 cache flash invalidate */ + ulong dis_derpc: 2; /* Disable d-ERAT parity checking */ + ulong dis_derpg: 1; /* Disable d-ERAT parity generation */ + ulong dis_derat: 2; /* Disable d-ERAT */ + ulong dis_dctpc: 2; /* Dis data cache tag paritiy checking */ + ulong dis_dctpg: 1; /* Dis data cache tag paritiy generation */ + ulong dis_dcset: 2; /* Disable data cache set */ + ulong dis_dcpc: 2; /* Disable data cache paritiy checking */ + ulong dis_dcpg: 1; /* Disable data cache paritiy generation */ + ulong dis_dcrtpc: 2; /* Disable data cache real add tag parity */ + ulong dis_tlbpc: 4; /* Disable TLB paritiy checking */ + ulong dis_tlbpg: 1; /* Disable TLB paritiy generation */ + ulong dis_tlbset: 4; /* Disable TLB set */ + ulong dis_slbpc: 1; /* Disable SLB paritiy checking */ + ulong dis_slbpg: 1; /* Disable SLB paritiy generation */ + ulong mck_inj: 1; /* Machine check inject enable */ + ulong dis_stfwd: 1; /* Disbale store forwarding */ + ulong lpes_1: 1; /* LPAR Environment Selector bit 1 */ + ulong rmlr_0: 1; /* RMLR 0 */ ulong _reserved: 1; ulong dis_splarx: 1; /* Disable spec. lwarx/ldarx */ ulong lg_pg_dis: 1; /* Disable large page support */ - ulong lpid01: 2; /* LPAR ID bits 0:1 */ + ulong lpid_0_1: 2; /* LPAR ID bits 0:1 */ } bits; ulong word; }; union hid5 { struct hid5_bits { - ulong _reserved_0_31: 32; - ulong hrmor: 16; - ulong _reserver_48_49:2; - ulong _unused_50_55: 6; - ulong DCBZ_size: 1; - ulong DCBZ32_ill: 1; - ulong _unused_58_63: 6; + ulong _reserved_0_31: 32; + ulong hrmor_0_15: 16; + ulong _reserved_48_49: 2; + ulong DC_mck: 1; /* Machine check enabled for dcache errors */ + ulong dis_pwrsave: 1; /* Dis pwrsave on on L1 and d-ERAT */ + ulong force_G: 1; /* Force gaurded load */ + ulong DC_repl: 1; /* D-Cache replacement algo */ + ulong hwr_stms: 1; /* Number of available HW prefetch streams */ + ulong dst_noop: 1; /* D-stream Touch no-op */ + ulong DCBZ_size: 1; /* make dcbz size 32 bytes */ + ulong DCBZ32_ill: 1; /* make dzbz 32byte illeagal */ + ulong tlb_map: 1; /* TLB mapping */ + ulong lmq_port: 1; /* Demand miss (LMQ to STS) */ + ulong lmq_size_0: 1; /* number of outstanding req. to STS */ + ulong _reserved_61: 1; + ulong tch_nop: 1; /* make dcbtand dcbtst ack like no-ops */ + ulong lmq_size_1: 1; /* second bit to lmq_size_0 */ } bits; ulong word; }; diff --git a/xen/include/asm-powerpc/powerpc64/processor.h b/xen/include/asm-powerpc/powerpc64/processor.h index 5036ed388e..8ad97a09a0 100644 --- a/xen/include/asm-powerpc/powerpc64/processor.h +++ b/xen/include/asm-powerpc/powerpc64/processor.h @@ -138,6 +138,11 @@ static inline void mthid0(ulong val) __asm__ __volatile__ ( "sync\n" "mtspr %0, %1\n" + "mfspr %1, %0\n" + "mfspr %1, %0\n" + "mfspr %1, %0\n" + "mfspr %1, %0\n" + "mfspr %1, %0\n" "isync\n" : : "i"(SPRN_HID0), "r"(val)); } @@ -153,6 +158,7 @@ static inline void mthid1(ulong val) __asm__ __volatile__ ( "sync\n" "mtspr %0, %1\n" + "mtspr %0, %1\n" "isync\n" : : "i"(SPRN_HID1), "r"(val)); } @@ -189,5 +195,23 @@ static inline void mthid5(ulong val) : : "i"(SPRN_HID5), "r"(val)); } +static inline void mthrmor(ulong val) +{ + __asm__ __volatile__ ( + "sync\n" + "mtspr %0, %1\n" + "isync\n" + : : "i"(SPRN_HRMOR), "r"(val)); +} + +static inline void mthior(ulong val) +{ + __asm__ __volatile__ ( + "sync\n" + "mtspr %0, %1\n" + "isync\n" + : : "i"(SPRN_HIOR), "r"(val)); +} + #endif /* __ASSEMBLY__ */ #endif diff --git a/xen/include/asm-powerpc/processor.h b/xen/include/asm-powerpc/processor.h index dbecadbdab..62a17545e6 100644 --- a/xen/include/asm-powerpc/processor.h +++ b/xen/include/asm-powerpc/processor.h @@ -42,6 +42,7 @@ extern void show_execution_state(struct cpu_user_regs *); extern void show_backtrace(ulong sp, ulong lr, ulong pc); extern unsigned int cpu_extent_order(void); extern unsigned int cpu_default_rma_order_pages(void); +extern int cpu_rma_valid(unsigned int log); extern uint cpu_large_page_orders(uint *sizes, uint max); extern void cpu_initialize(int cpuid); extern void cpu_init_vcpu(struct vcpu *); @@ -49,7 +50,11 @@ extern void save_cpu_sprs(struct vcpu *); extern void load_cpu_sprs(struct vcpu *); /* XXX this could also land us in GDB */ -#define dump_execution_state() trap() +#define dump_execution_state() BUG() + +extern void __warn(char *file, int line); +#define WARN() __warn(__FILE__, __LINE__) +#define WARN_ON(_p) do { if (_p) WARN(); } while ( 0 ) #define ARCH_HAS_PREFETCH static inline void prefetch(const void *x) {;} diff --git a/xen/include/asm-powerpc/reg_defs.h b/xen/include/asm-powerpc/reg_defs.h index 6d1769e8a1..bc8d772b63 100644 --- a/xen/include/asm-powerpc/reg_defs.h +++ b/xen/include/asm-powerpc/reg_defs.h @@ -154,6 +154,7 @@ #define SPRN_HSPRG0 304 #define SPRN_HSPRG1 305 #define SPRN_HDEC 310 +#define SPRN_HIOR 311 #define SPRN_RMOR 312 #define SPRN_HRMOR 313 #define SPRN_HSRR0 314 diff --git a/xen/include/asm-powerpc/shadow.h b/xen/include/asm-powerpc/shadow.h index d8b61ab328..e58191a7e9 100644 --- a/xen/include/asm-powerpc/shadow.h +++ b/xen/include/asm-powerpc/shadow.h @@ -26,22 +26,11 @@ #define shadow_mode_translate(_d) (1) #define shadow_mode_refcounts(_d) (1) -#define __translate_gpfn_to_mfn(_d, gpfn) \ - ( (shadow_mode_translate(_d)) \ - ? translate_gpfn_to_mfn(_d, gpfn) \ - : (gpfn) ) - #define __mfn_to_gpfn(_d, mfn) \ ( (shadow_mode_translate(_d)) \ ? machine_to_phys_mapping[(mfn)] \ : (mfn) ) -static inline unsigned long -translate_gpfn_to_mfn(struct domain *rd, unsigned long gpfn) -{ - trap(); - return 0; -} extern void guest_physmap_add_page( struct domain *d, unsigned long gpfn, unsigned long mfn); @@ -64,7 +53,7 @@ extern unsigned int shadow_teardown(struct domain *d); extern unsigned int shadow_set_allocation( struct domain *d, unsigned int megabytes, int *preempted); -/* Return the size of the shadow pool, rounded up to the nearest MB */ +/* Return the size of the shadow2 pool, rounded up to the nearest MB */ static inline unsigned int shadow_get_allocation(struct domain *d) { return (1ULL << (d->arch.htab.order + PAGE_SHIFT)) >> 20; diff --git a/xen/include/asm-powerpc/smp.h b/xen/include/asm-powerpc/smp.h index 7c65789eac..c3fbba8b71 100644 --- a/xen/include/asm-powerpc/smp.h +++ b/xen/include/asm-powerpc/smp.h @@ -27,7 +27,7 @@ extern int smp_num_siblings; /* revisit when we support SMP */ -#define get_hard_smp_processor_id(i) i +#define get_hard_smp_processor_id(i) (global_cpu_table[i]->whoami) #define raw_smp_processor_id() (parea->whoami) #define hard_smp_processor_id() raw_smp_processor_id() extern cpumask_t cpu_sibling_map[]; diff --git a/xen/include/asm-powerpc/system.h b/xen/include/asm-powerpc/system.h index 3d88d77ce0..7eb41c9325 100644 --- a/xen/include/asm-powerpc/system.h +++ b/xen/include/asm-powerpc/system.h @@ -22,10 +22,10 @@ #define _ASM_SYSTEM_H_ #include +#include #include #include #include -#include #include #define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr)))) @@ -139,7 +139,7 @@ __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) { switch (size) { case 2: - trap(); return 0; /* XXX implement __cmpxchg_u16 ? */ + BUG(); return 0; /* XXX implement __cmpxchg_u16 ? */ case 4: return __cmpxchg_u32(ptr, old, new); case 8: -- 2.30.2